package chapter08.pool;

import lombok.extern.slf4j.Slf4j;

import java.util.HashSet;
import java.util.concurrent.TimeUnit;

@Slf4j
public class ThreadPool {
    // 任务队列
    private BlockingQueue<Runnable> taskQueue;

    // 线程集合
    private HashSet<Worker> workers=new HashSet<>();

    // 核心线程数
    private int coresize;

    // 获取任务的超时时间
    private long timeout;

    //时间单位
    private TimeUnit timeUnit;

    // 任务策略
    private RejectPolicy<Runnable> rejectPolicy;
//    public ThreadPool(long timeout, TimeUnit timeUnit,int queueCapcity) {
//        this.coresize = coresize;// 获取本机cpu核心数
//        this.timeout = timeout;
//        this.timeUnit = timeUnit;
//        this.taskQueue=new BlockingQueue<>(queueCapcity);
//    }

    public ThreadPool(int coresize, long timeout, TimeUnit timeUnit,int queueCapcity,RejectPolicy<Runnable> rejectPolicy) {
        this.coresize = coresize;
        this.timeout = timeout;
        this.timeUnit = timeUnit;
        this.taskQueue=new BlockingQueue<>(queueCapcity);
        this.rejectPolicy=rejectPolicy;
    }

    public void execute(Runnable task){
        // 1. 判断当前任务是否为空
        // 2. 判断当前线程数是否大于核心数
        // 3. 线程数大于核心数，任务放入等待队列中去
        if(task!=null){
            synchronized (workers){
                if (workers.size()<coresize){
                    Worker worker = new Worker(task);
                    workers.add(worker);
                    log.debug("add worker:{}",worker);
                    worker.start();
                }else {
                    taskQueue.tryPut(rejectPolicy,task);
                }
            }
        }
    }

    private class Worker extends Thread{
        private Runnable task;
        public Worker(Runnable task){
            this.task=task;
        }

        @Override
        public void run() {
            // 运行任务
//            while (task!=null||(task=taskQueue.take())!=null){
            while (task!=null||(task=taskQueue.poll(timeout,timeUnit))!=null){
                // 执行任务
                try {
                    log.debug("task bengin to run：{}",task);
                    task.run();
                }catch (Exception e){
                    e.printStackTrace();
                }finally {
                    task=null;
                }
            }
            // 执行完任务后线程结束，删除该线程
            synchronized (workers){
                log.debug("wroker kill :{}",this);
                workers.remove(this);
            }
        }
    }

    @FunctionalInterface// 拒绝策略
    interface RejectPolicy<T>{
        void reject(BlockingQueue<T> queue,T task);
    }
}
